package us.wili.dev.netty.service.impl;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.wili.dev.netty.model.game.BetPool;
import us.wili.dev.netty.model.game.Player;
import us.wili.dev.netty.service.NettyBetPoolService;
import us.wili.dev.netty.service.NettyRoomService;
import us.wili.dev.netty.util.CardUtil;

import java.util.*;

@Service
public class NettyBetPoolServiceImpl implements NettyBetPoolService {

    @Autowired
    private NettyRoomService roomService;
    @Override
    public void subBetPoolList(List<BetPool> betPoolList, Map<Integer, Long> betMap, List<Player> ingamePlayers) {
        //对map按照值排序
        betMap = sortMapByValue(betMap);
        Boolean complete =false;
        while (!complete){
            complete =true;
            //该分池总金额
            Long betSum = 0l;
            //该分池单个金额
            Long thisBet = 0l;
            BetPool pool = new BetPool();
            for (Map.Entry<Integer,Long> e :betMap.entrySet()){
                if (e.getValue()!=0){
                    complete =false;
                    if (thisBet ==0){
                        thisBet =e.getValue();
                    }
                    betSum = betSum+thisBet;
                    //减去本轮单个金额;
                    e.setValue(e.getValue()-thisBet);
                    //加入betpool
                    Player p = roomService.getPlayerBySeatNum(e.getKey(),ingamePlayers);
                    if (p!=null){
                        pool.getBetPlayerList().add(p);
                    }
                }
            }
            pool.setBetSum(betSum);
            if (pool.getBetSum()!=0){
                betPoolList.add(pool);
            }
        }
    }

    @Override
    public List<Player> compareCardsToWinList(List<Player> poolPlayer, Map<Integer, List<Integer>> finalCardsMap) {
        List<Player> winPlayerList = new ArrayList<>();
        List<Integer> listold = null;
        if (finalCardsMap.size() == 0) {
            return null;
        }
        for (Map.Entry<Integer,List<Integer>> e : finalCardsMap.entrySet()){
            //判断是否在本分池内
            Boolean inThisPool = false;
            for (Player p : poolPlayer) {
                if (p!=null&&!p.isFold()&&e.getKey()==p.getSeatNum()){
                    inThisPool =true;
                    break;
                }
            }
            //不在分池内
            if (!inThisPool){
                continue;
            }
            //旧卡组为空，则加入
            if (listold ==null){
                listold = e.getValue();
                System.out.printf("getPlayerBySeatNum begin seatNum:" + e.getKey() + " poolPlayers:"
                        + JSON.toJSONString(poolPlayer));
                Player wp = roomService.getPlayerBySeatNum(e.getKey(),poolPlayer);
                if (wp != null){
                    winPlayerList.add(wp);
                }else {
                    System.out.printf("winPlayerList.add e.getKey():" + e.getKey() + "wp not in poolPlayers");
                }
                System.out.printf("winPlayerList.add e.getKey():" + e.getKey());
            }else {
                List<Integer> listNew = e.getValue();
                //比较新旧牌组 大或相等则清空winplaylist，加入新卡组玩家
                System.out.printf("compareCardsToWinList CardUtil.compareValue listNew:" + listNew + " listold" + listold);
                int result = CardUtil.compareValue(e.getValue(),listold);
                System.out.printf("compareCardsToWinList CardUtil.compareValue result:" + result);
                if (result==1){
                    winPlayerList.clear();
                    winPlayerList.add(roomService.getPlayerBySeatNum(e.getKey(),poolPlayer));
                    listold=listNew;
                }else if (result==0){
                    winPlayerList.add(roomService.getPlayerBySeatNum(e.getKey(),poolPlayer));
                }
            }
        }
        return winPlayerList;
    }

    @Override
    public void increasePlayerChips(Player p, Long chips) {
        synchronized (p) {
            p.setBodyChips(p.getBodyChips() + chips);
        }
    }


    /**
     *按值排序一个map
     * @param oriMap
     * @return
     */
    public static Map<Integer, Long> sortMapByValue(Map<Integer, Long> oriMap) {
        Map<Integer, Long> sortedMap = new LinkedHashMap<Integer, Long>();
        if (oriMap != null && !oriMap.isEmpty()) {
            List<Map.Entry<Integer, Long>> entryList = new ArrayList<Map.Entry<Integer, Long>>(oriMap.entrySet());
            Collections.sort(entryList, new Comparator<Map.Entry<Integer, Long>>() {
                public int compare(Map.Entry<Integer, Long> entry1, Map.Entry<Integer, Long> entry2) {
                    Long value1 = 0l, value2 = 0l;
                    value1 = entry1.getValue();
                    value2 = entry2.getValue();
                    return value1.compareTo(value2);
                }
            });
            Iterator<Map.Entry<Integer, Long>> iter = entryList.iterator();
            Map.Entry<Integer, Long> tmpEntry = null;
            while (iter.hasNext()) {
                tmpEntry = iter.next();
                sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
            }
        }
        return sortedMap;
    }
}
